Keras Multi-layer Perceptron
Tensorflow Premade Estimators
Tensorflow Image and Text Classification
This article is based on the TensorFlow Image Classification article where we demonstrate image classification using TensorFlow. The dataset that we use here is a filtered version of Dogs vs Cats dataset from Kaggle.
import os
import tensorflow as tf
def Get_Data(_URL, Remove = True):
# The dataset URL
File = _URL.split('/')[-1]
Full_Name = os.path.join(os.getcwd(), File)
# Download the dataset file from the URL
path_to_zip = tf.keras.utils.get_file(fname =Full_Name, origin=_URL, extract=True, cache_dir = os.getcwd())
PATH = os.path.join(os.path.dirname(path_to_zip), 'datasets', File.split('.')[0])
# Deleting the zip file
if Remove:
os.remove(File)
return PATH
#-----------------------------------------------------------------
_URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'
PATH = Get_Data(_URL)
Downloading data from https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip 68608000/68606236 [==============================] - 2s 0us/step 68616192/68606236 [==============================] - 2s 0us/step
from HD_DirTools import Path_Tree
Path_Tree(PATH)
======================= cats_and_dogs_filtered: ======================= └── train: └── cats: 1000 JPG files cat.0.jpg, cat.1.jpg, cat.10.jpg, cat.100.jpg, cat.101.jpg, ... └── dogs: 1000 JPG files dog.0.jpg, dog.1.jpg, dog.10.jpg, dog.100.jpg, dog.101.jpg, ... └── validation: └── cats: 500 JPG files cat.2000.jpg, cat.2001.jpg, cat.2002.jpg, cat.2003.jpg, cat.2004.jpg, ... └── dogs: 500 JPG files dog.2000.jpg, dog.2001.jpg, dog.2002.jpg, dog.2003.jpg, dog.2004.jpg, ...
from HD_DirTools import Data_Info
DataFrame_Info, DataDirs = Data_Info(PATH)
display(DataFrame_Info.set_index(['Set' , 'Subset']).T)
| Set | Train | Validation | ||
|---|---|---|---|---|
| Subset | Cats | Dogs | Cats | Dogs |
| Size | 1000 | 1000 | 500 | 500 |
batch_size = 128
epochs = 15
Img_Height = 150
Img_Width = 150
image_gen_train = tf.keras.preprocessing.image.ImageDataGenerator(
# Rescaling the tensors from values between 0 and 255 to values between 0 and 1
rescale=1./255,
# Applying 45 degrees of rotation randomly
rotation_range=45,
# Range for random horizontal shifts.
width_shift_range=.15,
# Range for random vertical shifts.
height_shift_range=.15,
# applying random horizontal flip augmentation
horizontal_flip=True,
# Applying a zoom augmentation to the dataset to zoom images up to 50%
zoom_range=0.5
)
print('Train Data:')
# flow_from_directory method load images from the disk
train_data_gen = image_gen_train.flow_from_directory(batch_size=batch_size,
directory=DataDirs['train'],
shuffle=True,
target_size=(Img_Height, Img_Width),
class_mode='binary')
Train Data: Found 2000 images belonging to 2 classes.
import matplotlib.pyplot as plt
def plotImages(images_arr, s = 3.4, Title = False):
fig, axes = plt.subplots(1, len(images_arr), figsize=(s* len(images_arr),s))
axes = axes.flatten()
for img, ax in zip( images_arr, axes):
ax.imshow(img)
ax.axis('off')
_ = fig.tight_layout()
_ = fig.subplots_adjust(wspace= 5e-3)
if Title:
_ = fig.suptitle(Title, y = 1.05, weight = 'bold', fontsize = 18)
sample_images, _ = next(train_data_gen)
plotImages(sample_images[:4], Title = 'Four Random Pictures from the Train Sample')
augmented_images = [train_data_gen[0][0][0] for i in range(5)]
plotImages(augmented_images, Title = 'Original and Augmented Pictures', s = 3)
validation_image_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
print('Validation Data:')
val_data_gen = validation_image_generator.flow_from_directory(batch_size = batch_size,
directory = DataDirs['validation'],
target_size = (Img_Height, Img_Width),
class_mode = 'binary')
sample_images, _ = next(val_data_gen)
plotImages(sample_images[:4], Title = 'Four Random Pictures from the Train Sample')
Validation Data: Found 1000 images belonging to 2 classes.
We use Keras Sequential model for creating a model.
model = tf.keras.models.Sequential(name = 'CNN')
model.add(tf.keras.layers.Conv2D(16, 3, padding='same', activation='relu', input_shape=(Img_Height, Img_Width ,3)))
model.add(tf.keras.layers.MaxPooling2D())
# regularization
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.Conv2D(32, 3, padding='same', activation='relu'))
model.add(tf.keras.layers.MaxPooling2D())
model.add(tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu'))
model.add(tf.keras.layers.MaxPooling2D())
# regularization
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dense(1))
model.summary()
tf.keras.utils.plot_model(model, show_shapes=True, show_layer_names=False, expand_nested = True, rankdir = 'TB')
Model: "CNN"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 150, 150, 16) 448
max_pooling2d (MaxPooling2D (None, 75, 75, 16) 0
)
dropout (Dropout) (None, 75, 75, 16) 0
conv2d_1 (Conv2D) (None, 75, 75, 32) 4640
max_pooling2d_1 (MaxPooling (None, 37, 37, 32) 0
2D)
conv2d_2 (Conv2D) (None, 37, 37, 64) 18496
max_pooling2d_2 (MaxPooling (None, 18, 18, 64) 0
2D)
dropout_1 (Dropout) (None, 18, 18, 64) 0
flatten (Flatten) (None, 20736) 0
dense (Dense) (None, 512) 10617344
dense_1 (Dense) (None, 1) 513
=================================================================
Total params: 10,641,441
Trainable params: 10,641,441
Non-trainable params: 0
_________________________________________________________________
Compiling and fitting the model
model.compile(optimizer = 'adam', loss = tf.keras.losses.BinaryCrossentropy(from_logits=True), metrics = ['accuracy'])
history = model.fit(train_data_gen,
steps_per_epoch = DataFrame_Info.loc[DataFrame_Info['Set'] == 'Train','Size'].sum() // batch_size,
epochs = epochs,
validation_data = val_data_gen,
validation_steps = DataFrame_Info.loc[DataFrame_Info['Set'] == 'Validation','Size'].sum() // batch_size)
# clear_output()
Epoch 1/15 15/15 [==============================] - 19s 1s/step - loss: 1.3590 - accuracy: 0.5085 - val_loss: 0.6936 - val_accuracy: 0.5022 Epoch 2/15 15/15 [==============================] - 12s 780ms/step - loss: 0.6932 - accuracy: 0.5021 - val_loss: 0.6931 - val_accuracy: 0.4955 Epoch 3/15 15/15 [==============================] - 12s 809ms/step - loss: 0.6932 - accuracy: 0.4989 - val_loss: 0.6932 - val_accuracy: 0.4855 Epoch 4/15 15/15 [==============================] - 12s 803ms/step - loss: 0.6930 - accuracy: 0.5011 - val_loss: 0.6927 - val_accuracy: 0.4978 Epoch 5/15 15/15 [==============================] - 12s 805ms/step - loss: 0.6930 - accuracy: 0.4979 - val_loss: 0.6914 - val_accuracy: 0.5078 Epoch 6/15 15/15 [==============================] - 12s 807ms/step - loss: 0.6912 - accuracy: 0.4957 - val_loss: 0.6897 - val_accuracy: 0.5056 Epoch 7/15 15/15 [==============================] - 12s 770ms/step - loss: 0.6903 - accuracy: 0.4979 - val_loss: 0.6866 - val_accuracy: 0.5022 Epoch 8/15 15/15 [==============================] - 12s 763ms/step - loss: 0.6885 - accuracy: 0.5005 - val_loss: 0.6750 - val_accuracy: 0.5033 Epoch 9/15 15/15 [==============================] - 12s 792ms/step - loss: 0.6882 - accuracy: 0.5021 - val_loss: 0.6855 - val_accuracy: 0.5056 Epoch 10/15 15/15 [==============================] - 12s 770ms/step - loss: 0.6843 - accuracy: 0.5027 - val_loss: 0.6872 - val_accuracy: 0.4944 Epoch 11/15 15/15 [==============================] - 12s 769ms/step - loss: 0.6790 - accuracy: 0.5123 - val_loss: 0.6956 - val_accuracy: 0.5290 Epoch 12/15 15/15 [==============================] - 12s 787ms/step - loss: 0.6741 - accuracy: 0.5401 - val_loss: 0.6756 - val_accuracy: 0.5234 Epoch 13/15 15/15 [==============================] - 12s 770ms/step - loss: 0.6722 - accuracy: 0.5443 - val_loss: 0.6595 - val_accuracy: 0.5547 Epoch 14/15 15/15 [==============================] - 12s 774ms/step - loss: 0.6559 - accuracy: 0.5716 - val_loss: 0.6576 - val_accuracy: 0.5815 Epoch 15/15 15/15 [==============================] - 12s 787ms/step - loss: 0.6613 - accuracy: 0.5593 - val_loss: 0.6345 - val_accuracy: 0.6027
def Search_List(Key, List): return [s for s in List if Key in s]
Metrics_Names = {'loss':'Loss', 'accuracy':'Accuracy', 'mae':'MAE', 'mse':'MSE', 'recall': 'Recall'}
import pandas as pd
import numpy as np
from HD_DeepLearning import history2Table
Validation_Table = Search_List('val_',history.history.keys())
Train_Table = list(set( history.history.keys()) - set(Validation_Table))
Validation_Table = pd.DataFrame(np.array([history.history[x] for x in Validation_Table]).T, columns = Validation_Table)
Train_Table = pd.DataFrame(np.array([history.history[x] for x in Train_Table]).T, columns = Train_Table)
Validation_Table.columns = [x.replace('val_','') for x in Validation_Table.columns]
Train_Table = history2Table(Train_Table, Metrics_Names)
Validation_Table = history2Table(Validation_Table, Metrics_Names)
# Train Set Score
score = model.evaluate(train_data_gen, batch_size = batch_size, verbose = 0)
score = pd.DataFrame(score, index = model.metrics_names).T
score.index = ['Train Set Score']
# Validation Set Score
Temp = model.evaluate(val_data_gen, batch_size = batch_size, verbose = 0)
Temp = pd.DataFrame(Temp, index = model.metrics_names).T
Temp.index = ['Validation Set Score']
score = pd.concat([score, Temp])
score.rename(columns= Metrics_Names, inplace = True)
score = score.reindex(sorted(score.columns), axis=1)
display(score.style.format(precision=4))
| Accuracy | Loss | |
|---|---|---|
| Train Set Score | 0.5745 | 0.6460 |
| Validation Set Score | 0.6050 | 0.6382 |
from HD_DeepLearning import Plot_history
PD = dict(row_heights = [0.4, 0.6], lw = 1.5, font_size=12, height = 700, yLim = 1,
th_line_color = 'Navy', th_fill_color='darkslategray', table_columnwidth = [0.4, 0.4, 0.4, 0.4],
tc_line_color = 'Navy', tc_fill_color = None, title_x = 0.46, title_y = 0.94, tb_cell_heigh = 20,
Number_Format = '%.4e')
Plot_history(Train_Table, PD, Title = 'Train Set', Table_Rows = 10, Colors = ['DarkGreen', 'Red'])
Plot_history(Validation_Table, PD, Title = 'Validation Set', Table_Rows = 10, Colors = [ 'DarkGreen', 'Red'])
Here, we only went through a few iterations; however, we need to train the model for more iterations to get acceptable results.
# del downloaded images
import shutil
shutil.rmtree('datasets/cats_and_dogs_filtered')